package com.chat.api.web.service;


import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.Sheet;
import com.chat.api.common.exception.ApiException;
import com.chat.api.listener.ExcelListener;
import com.chat.api.utils.PoiReadExcelData;
import com.chat.api.utils.ResultUtil;
import com.chat.api.utils.util.ParamUtil;
import com.chat.api.web.po.BlogBean;
import com.chat.api.web.po.UserBean;
import com.chat.api.web.vo.MessageEntity;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;

@Service
public class ActivityService {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private ProcessEngine processEngine;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private BlogService blogService;
    @Autowired
    private UserService userService;
    @Autowired
    private ChatService chatService;

    /**
     * 部署博客审批流程
     * @param request
     * @param userBean
     */
    public void deployActivity(HttpServletRequest request, UserBean userBean){
        try {
            Deployment deployment = processEngine.getRepositoryService()
                    .createDeployment()
                    .name("博客审批")
                    .addClasspathResource("processes/approve.bpmn")
                    .deploy();
            System.out.println("部署ID："+deployment.getId());//1
            System.out.println("部署时间："+deployment.getDeploymentTime());
            //添加审批人（站主）信息
            User user1 = identityService.createUserQuery().userFirstName("刘涛").singleResult();
            if (user1 != null){
                return;
            }
            User user = identityService.newUser(userBean.getId().toString());
            user.setFirstName(userBean.getName());
            user.setLastName(userBean.getName());
            user.setPassword(userBean.getPassword());
            identityService.saveUser(user);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 开启博客审批流程
     * @param blogBean
     */
    public void openBlogApproval(BlogBean blogBean) {
        try {
            //获取审批流程id
            Deployment de = processEngine.getRepositoryService().createDeploymentQuery()
                    .deploymentName("博客审批").singleResult();
            //开启一个新的审批流程
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(de.getId()).singleResult();
            ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinition.getId());
            String processInstanceId = processInstance.getProcessInstanceId();

            User user1 = identityService.createUserQuery().userId(blogBean.getUserId().toString()).singleResult();
            if (user1 == null) {
                User user = identityService.newUser(blogBean.getUserId().toString());
                user.setFirstName(blogBean.getAuthorName());
                user.setLastName(blogBean.getAuthorName());
                user.setPassword("123456");
                identityService.saveUser(user);
            }

            //提交审批
            Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
            HashMap<String, Object> map = new HashMap<>();
            User user = identityService.createUserQuery().userFirstName("刘涛").singleResult();
            map.put("userId", user.getId());
            taskService.complete(task.getId(),map);

            blogBean.setProcInstId(task.getProcessInstanceId());
            blogService.save(blogBean);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 审批博客
     * @param blogId
     * @param result
     * @return
     */
    public MessageEntity approvalBlog(Long blogId,Integer result){
        try {
            String message = "";
            BlogBean blogBean = blogService.getBeanById(blogId);
            HashMap<String, Object> map = new HashMap<>();
            map.put("result", result);
            Task task1 = taskService.createTaskQuery().processInstanceId(blogBean.getProcInstId()).singleResult();
            taskService.complete(task1.getId(),map);
            if (result == 1){
                blogBean.setStatus("通过");//通过
                message = "您的博客：《" + blogBean.getTitle() + "》  审核已通过,可以在博客列表里进行查看。。。";
            }else {
                blogBean.setStatus("未通过");//未通过
                message = "您的博客：《" + blogBean.getTitle() + "》  审核未通过,请删除不正当言论后重新发表。。。";
                //直接终止流程
                Task task = taskService.createTaskQuery().taskId(blogBean.getProcInstId()).singleResult();
                runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"删除流程");
            }

            blogService.save(blogBean);
            chatService.sendMsg(blogBean.getUserId(),message);
            return ResultUtil.success("审核完成！！！");
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.fail("审核失败，请看日志详情！！！");
        }
    }

    /**
     * 查看审批进度图
     */
    public void getApprovalRate(Long id, HttpServletResponse response) {
        try {
            BlogBean blogBean = blogService.getBeanById(id);
            Task task = taskService.createTaskQuery().processInstanceId(blogBean.getProcInstId()).singleResult();
            InputStream is = getDiagram(task.getProcessInstanceId());
            if (is == null) return ;
            response.setContentType("image/png");

            BufferedImage image = ImageIO.read(is);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "png", out);

            is.close();
            out.close();
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("系统繁忙，请稍后再试！！！");
        }
    }

    //获取流程审批进程图
    public InputStream getDiagram(String processInstanceId) {
        //获得流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        String processDefinitionId = StringUtils.EMPTY;
        if (processInstance == null) {
            //查询已经结束的流程实例
            HistoricProcessInstance processInstanceHistory =
                    historyService.createHistoricProcessInstanceQuery()
                            .processInstanceId(processInstanceId).singleResult();
            if (processInstanceHistory == null)
                return null;
            else
                processDefinitionId = processInstanceHistory.getProcessDefinitionId();
        } else {
            processDefinitionId = processInstance.getProcessDefinitionId();
        }

        //使用宋体
        String fontName = "宋体";
        //获取BPMN模型对象
        BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
        //获取流程实例当前的节点，需要高亮显示
        List<String> currentActs = Collections.EMPTY_LIST;
        if (processInstance != null)
            currentActs = runtimeService.getActiveActivityIds(processInstance.getId());

        return processEngine.getProcessEngineConfiguration()
                .getProcessDiagramGenerator()
                .generateDiagram(model, "png", currentActs, new ArrayList<String>(),
                        fontName, fontName, fontName, null, 1.0);
    }

    /**
     * 根据博客id删除审批流
     * @param ids
     */
    public void deleteByBlogId(String ids) {
        try {
            Long id = ParamUtil.getLongParameter(ids, -1L);
            BlogBean blogBean = blogService.getBeanById(id);
            if (blogBean == null) return;
            Task task = taskService.createTaskQuery().taskId(blogBean.getProcInstId()).singleResult();
            if (task == null) return;
            runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"终止流程");
            String message = "非常抱歉，您的博客：《" + blogBean.getTitle() + "》  审核未通过。。。";
            chatService.sendMsg(blogBean.getUserId(),message);
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("删除博客的审批流程异常");
        }
    }

    public static MessageEntity test() {
        String path = "/usr/local/software/tomcat/tomcat9/webapps/upload/用例21：参数含特殊格式-3表.xlsx";
        File file = new File(path);
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Map<String, Object> excelMap = new LinkedHashMap<>();
        List<Sheet> sheets = new ArrayList<>();
        ExcelReader reader = null;
        ExcelListener excelListener = new ExcelListener();
        try {
            reader = EasyExcelFactory.getReader(fileInputStream, excelListener);
        }catch (ExcelCommonException e){
            throw new ExcelCommonException();
        }
        sheets = reader.getSheets();
        //获取excel所有数据
        for (Sheet sheet : sheets) {
            List<List<String>> data = new ArrayList<>();
            try {
                reader.read(sheet);
            }catch (ExcelAnalysisException e){
                throw new FormatterClosedException();
            }
            data = excelListener.getDatas();
            excelMap.put(sheet.getSheetName(), data);
            excelListener.initialize();
        }

//        excelMap = PoiReadExcelData.readExcel(inputStream);
        System.out.println(excelMap);
        return ResultUtil.success(excelMap);
    }

    public static void main(String[] args) {
        test();
    }


}
